package encaps.utils;

import encaps.action.DeleteLogAction;
import encaps.action.ViewLogAction;
import encaps.entities.Role;
import encaps.logging.LogLocal;
import encaps.logging.LogLocalHome;
import encaps.resources.Grants;
import encaps.resources.Labels;
import encaps.resources.Response;
import encaps.security.SecuritySystem;
import java.util.Collection;
import javax.naming.NamingException;
import org.jdom.Element;

public class LogViewer {

    public Element getResult(int pageNumber, int recordsPerPage, int fromRecord, String userRole) throws SystemException {
        int pageCount = getPageCount(recordsPerPage);
        Collection searchResult = find(recordsPerPage, fromRecord);
        Element result = toXMLElement(searchResult, SecuritySystem.getRole(userRole), pageCount, pageNumber);
        return result;
    }

    protected Collection find(int recordsPerPage, int fromRecord) throws SystemException {
        try {
            LogLocalHome LogHome = EntityUtil.getLogHome();
            Collection<LogLocal> result = LogHome.findPaged(fromRecord, recordsPerPage);
            return result;
        } catch (NamingException ex) {
            throw new SystemException(Labels.getLabel(Labels.CANNOT_FIND_LOCAL_HOME_OBJECT_MESSAGE), ex);
        }
    }

    public Element toXMLElement(Collection result, Role userRole, int pageCount, int currentPage) throws SystemException {
        Element resultXML = XMLHelper.createElement(Response.RESPONSE);
        Element e = XMLHelper.addChild(resultXML, Response.TABLE);
        //Создаем заголовок страницы
        XMLHelper.addChild(e, Response.HEADER, Labels.getLabel(Labels.VIEW_LOG));
        //Создаем заголовки столбцов таблиц
        Element headers = XMLHelper.createElement(Response.COLUMN_HEADERS);
        Element logActionHeader = XMLHelper.addChild(headers, Response.COLUMN_HEADER);
        XMLHelper.addChild(logActionHeader, Response.COLUMN_HEADER_LABEL, Labels.getLabel(Labels.LOG_ACTION));
        Element userIdHeader = XMLHelper.addChild(headers, Response.COLUMN_HEADER);
        XMLHelper.addChild(userIdHeader, Response.COLUMN_HEADER_LABEL, Labels.getLabel(Labels.USER_ID));
        Element userNameHeader = XMLHelper.addChild(headers, Response.COLUMN_HEADER);
        XMLHelper.addChild(userNameHeader, Response.COLUMN_HEADER_LABEL, Labels.getLabel(Labels.USER_NAME));
        Element entityTypeHeader = XMLHelper.addChild(headers, Response.COLUMN_HEADER);
        XMLHelper.addChild(entityTypeHeader, Response.COLUMN_HEADER_LABEL, Labels.getLabel(Labels.ENTITY_TYPE));
        Element timeHeader = XMLHelper.addChild(headers, Response.COLUMN_HEADER);
        XMLHelper.addChild(timeHeader, Response.COLUMN_HEADER_LABEL, Labels.getLabel(Labels.TIME));
        //XMLHelper.addChild(headers, Response.COLUMN_HEADER, Labels.getLabel(Labels.ENTITY_TYPE));
        //XMLHelper.addChild(headers, Response.COLUMN_HEADER, Labels.getLabel(Labels.ENTITY_ID));
        //XMLHelper.addChild(headers, Response.COLUMN_HEADER, Labels.getLabel(Labels.ENTITY_NAME));
        XMLHelper.addChild(e, headers);
        //Заполняем таблицу
        XMLHelper.addChild(e, logToTableRows(result, userRole));
        //Заполняем информацию, необходимую для пагинации
        Element searchingParameters = XMLHelper.createElement(Response.SEARCHING_PARAMETERS);
        XMLHelper.addChild(searchingParameters, Response.PAGE_COUNT, pageCount);
        XMLHelper.addChild(searchingParameters, Response.CURRENT_PAGE, currentPage);
        XMLHelper.addChild(searchingParameters, Response.ENTITY_TYPE, ViewLogAction.ENTITY_TYPE);
        XMLHelper.addChild(searchingParameters, Response.ACTION_NAME, ViewLogAction.VIEW_LOG);
        XMLHelper.addChild(e, searchingParameters);
        return resultXML;
    }

    private Element logToTableRows(Collection<LogLocal> logs, Role role) throws SystemException {
        Element rows = XMLHelper.createElement(Response.ROWS);
        for (LogLocal log : logs) {
            Element row = XMLHelper.addChild(rows, Response.ROW);
            //Добавление ячеек в строку таблицы. Каждая ячейка соответствует
            //одному полю (одной колонке) таблицы
            Element cell = XMLHelper.addChild(row, Response.CELL, log.getAction());
            cell.setAttribute(Response.TYPE, Response.TEXT);
            cell = XMLHelper.addChild(row, Response.CELL, log.getUserId());
            cell.setAttribute(Response.TYPE, Response.TEXT);
            cell = XMLHelper.addChild(row, Response.CELL, log.getUserName());
            cell.setAttribute(Response.TYPE, Response.TEXT);
            if (log.getEntityType() != null) {
                cell = XMLHelper.addChild(row, Response.CELL, log.getEntityType());
            } else {
                cell = XMLHelper.addChild(row, Response.CELL, "-");
            }
            cell.setAttribute(Response.TYPE, Response.TEXT);
            try {
                cell = XMLHelper.addChild(row, Response.CELL, TypeConverter.convertToStringWithTime(log.getTime()));
                cell.setAttribute(Response.TYPE, Response.TEXT);
            } catch (ConversionException ex) {
                throw new SystemException(Labels.getLabel(Labels.CONVERSION_ERROR_MESSAGE), ex);
            }

            /*
             * if(log.getEntityType() != null) { cell = XMLHelper.addChild(row,
             * Response.CELL, log.getEntityType());
             * cell.setAttribute(Response.TYPE, Response.TEXT); cell =
             * XMLHelper.addChild(row, Response.CELL, log.getEntityId());
             * cell.setAttribute(Response.TYPE, Response.TEXT); cell =
             * XMLHelper.addChild(row, Response.CELL, log.getEntityName());
             * cell.setAttribute(Response.TYPE, Response.TEXT);
            }
             */
            //Добавляем ссылки на действия над фильмами
            //Ссылка на удаление
            if (role.hasGrant(Grants.DELETE_LOG)) {
                Element deleteLinkCell = XMLHelper.addChild(row, Response.CELL);
                deleteLinkCell.setAttribute(Response.TYPE, Response.LINK);
                deleteLinkCell.addContent(XMLHelper.createLink(Labels.getLabel(Labels.DELETE_LINK), DeleteLogAction.DELETE_LOG, log.getId()));
            }
        }
        return rows;
    }

    protected int getFoundRecordsCount() throws SystemException {
        try {
            LogLocalHome LogHome = EntityUtil.getLogHome();
            return LogHome.getLogCount();
        } catch (NamingException ex) {
            throw new SystemException(Labels.getLabel(Labels.CANNOT_FIND_LOCAL_HOME_OBJECT_MESSAGE), ex);
        }
    }

    private int getPageCount(int recordsPerPage) throws SystemException {
        int recordCount = getFoundRecordsCount();
        int pageCount = recordCount / recordsPerPage;
        if (recordCount % recordsPerPage > 0) {
            pageCount++;
        }
        return pageCount;
    }
}
